home *** CD-ROM | disk | FTP | other *** search
- /*
- * positioner.c
- *
- * Forms Object class: POSITIONER
- *
- * Written by: Mark Overmars
- *
- * Version 2.1 a
- * Date: Nov 6, 1992
- */
-
- #include <malloc.h>
- #include "gl/gl.h"
- #include <sys/types.h>
- #include "forms.h"
-
- /* The special information for positioners. */
- typedef struct {
- float xmin, ymin; /* minimal values */
- float xmax, ymax; /* maximal values */
- float xval, yval; /* current values */
- float xstep, ystep; /* step size to which values are rounded */
- int always; /* whether always returning value */
- } SPEC;
-
- static float flinear(float val, float smin, float smax, float gmin, float gmax)
- /* performs linear interpolation */
- {
- if (smin == smax) return gmax;
- else return gmin + (gmax - gmin) * (val - smin) / (smax - smin);
- }
-
- static void draw_positioner(FL_OBJECT *ob)
- /* Draws a positioner */
- {
- SPEC *sp = ((SPEC *)(ob->spec));
- float x1 = ob->x + FL_POSITIONER_BW + 1.0;
- float y1 = ob->y + FL_POSITIONER_BW + 1.0;
- float w1 = ob->w - 2.0 * FL_POSITIONER_BW - 2.0;
- float h1 = ob->h - 2.0 * FL_POSITIONER_BW - 2.0;
- float xx,yy;
- xx = flinear(sp->xval, sp->xmin, sp->xmax,x1,x1+w1-1.0);
- yy = flinear(sp->yval, sp->ymin, sp->ymax,y1,y1+h1-1.0);
- fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,ob->col1,FL_POSITIONER_BW);
- fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
- ob->lcol,ob->lsize,ob->lstyle,ob->label);
- fl_line(x1,yy,w1,1.0,ob->col2);
- fl_line(xx,y1,1.0,h1,ob->col2);
- }
-
- static int handle_mouse(FL_OBJECT *ob,float mx,float my)
- /* Handle a mouse position change */
- {
- SPEC *sp = ((SPEC *)(ob->spec));
- float x1 = ob->x + FL_POSITIONER_BW + 1.0;
- float y1 = ob->y + FL_POSITIONER_BW + 1.0;
- float w1 = ob->w - 2.0 * FL_POSITIONER_BW - 2.0;
- float h1 = ob->h - 2.0 * FL_POSITIONER_BW - 2.0;
- float oldx = sp->xval, oldy = sp->yval;
- sp->xval = flinear(mx, x1, x1+w1-1.0, sp->xmin, sp->xmax);
- sp->yval = flinear(my, y1, y1+h1-1.0, sp->ymin, sp->ymax);
- if (sp->xstep != 0.0) sp->xval = (int) (sp->xval/sp->xstep +0.5) * sp->xstep;
- if (sp->ystep != 0.0) sp->yval = (int) (sp->yval/sp->ystep +0.5) * sp->ystep;
- if (sp->xval < sp->xmin) sp->xval = sp->xmin;
- if (sp->xval > sp->xmax) sp->xval = sp->xmax;
- if (sp->yval < sp->ymin) sp->yval = sp->ymin;
- if (sp->yval > sp->ymax) sp->yval = sp->ymax;
- if (sp->xval != oldx || sp->yval != oldy)
- { fl_redraw_object(ob); return 1; }
- else
- { return 0; }
- }
-
- static int handle_positioner(FL_OBJECT *ob,int event,float mx,float my,char key)
- /* Handles an event */
- {
- SPEC *sp = (SPEC *) ob->spec;
- switch (event)
- {
- case FL_DRAW:
- draw_positioner(ob);
- return 0;
- case FL_PUSH:
- case FL_MOUSE:
- return ( handle_mouse(ob,mx,my) && sp->always);
- case FL_RELEASE:
- return (! sp->always);
- case FL_FREEMEM:
- free(ob->spec);
- return 0;
- }
- return 0;
- }
-
- /*------------------------------*/
-
- FL_OBJECT *fl_create_positioner(int type,float x,float y,float w,float h,char label[])
- /* creates an object */
- {
- FL_OBJECT *ob;
- ob = fl_make_object(FL_POSITIONER,type,x,y,w,h,label,handle_positioner);
- ob->boxtype = FL_POSITIONER_BOXTYPE;
- ob->col1 = FL_POSITIONER_COL1;
- ob->col2 = FL_POSITIONER_COL2;
- ob->align = FL_POSITIONER_ALIGN;
- ob->lcol = FL_POSITIONER_LCOL;
-
- ob->spec = (int *) fl_malloc(sizeof(SPEC));
- ((SPEC *)(ob->spec))->xmin = 0.0;
- ((SPEC *)(ob->spec))->xmax = 1.0;
- ((SPEC *)(ob->spec))->xval = 0.5;
- ((SPEC *)(ob->spec))->ymin = 0.0;
- ((SPEC *)(ob->spec))->ymax = 1.0;
- ((SPEC *)(ob->spec))->yval = 0.5;
- ((SPEC *)(ob->spec))->xstep = 0.0;
- ((SPEC *)(ob->spec))->ystep = 0.0;
-
- ((SPEC *)(ob->spec))->always = TRUE;
-
- return ob;
- }
-
- FL_OBJECT *fl_add_positioner(int type,float x,float y,float w,float h,char label[])
- /* Adds an object */
- {
- FL_OBJECT *ob;
- ob = fl_create_positioner(type,x,y,w,h,label);
- fl_add_object(fl_current_form,ob);
- return ob;
- }
-
- void fl_set_positioner_xvalue(FL_OBJECT *ob,float val)
- {
- ((SPEC *)(ob->spec))->xval = val;
- fl_redraw_object(ob);
- }
-
- void fl_set_positioner_yvalue(FL_OBJECT *ob,float val)
- {
- ((SPEC *)(ob->spec))->yval = val;
- fl_redraw_object(ob);
- }
-
- void fl_set_positioner_xbounds(FL_OBJECT *ob,float min,float max)
- {
- ((SPEC *)(ob->spec))->xmin = min;
- ((SPEC *)(ob->spec))->xmax = max;
- fl_redraw_object(ob);
- }
-
- void fl_set_positioner_ybounds(FL_OBJECT *ob,float min,float max)
- {
- ((SPEC *)(ob->spec))->ymin = min;
- ((SPEC *)(ob->spec))->ymax = max;
- fl_redraw_object(ob);
- }
-
- float fl_get_positioner_xvalue(FL_OBJECT *ob)
- { return ((SPEC *)(ob->spec))->xval; }
-
- float fl_get_positioner_yvalue(FL_OBJECT *ob)
- { return ((SPEC *)(ob->spec))->yval; }
-
- void fl_get_positioner_xbounds(FL_OBJECT *ob,float *min,float *max)
- {
- *min = ((SPEC *)(ob->spec))->xmin;
- *max = ((SPEC *)(ob->spec))->xmax;
- }
-
- void fl_get_positioner_ybounds(FL_OBJECT *ob,float *min,float *max)
- {
- *min = ((SPEC *)(ob->spec))->ymin;
- *max = ((SPEC *)(ob->spec))->ymax;
- }
-
- void fl_set_positioner_xstep(FL_OBJECT *ob, float value)
- /* Sets the step size to which values are rounded. */
- { ((SPEC *)(ob->spec))->xstep = value; }
-
- void fl_set_positioner_ystep(FL_OBJECT *ob, float value)
- /* Sets the step size to which values are rounded. */
- { ((SPEC *)(ob->spec))->ystep = value; }
-
- void fl_set_positioner_return(FL_OBJECT *ob, int value)
- /* Sets whether to return value all the time */
- { ((SPEC *)(ob->spec))->always = value; }
-
-